package com.t.bricks.bussiness.component.loginlog;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.t.bricks.bussiness.db.entity.loginlog.LoginLog;
import com.t.bricks.bussiness.service.loginlog.LoginLogService;
import com.t.bricks.model.Log;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.utils.spring.ModuleUtil;

/**
 * 用切面方式监听用户登录的数据操作
 */
@Aspect
@Component
public class LoginLogServiceAspect {
		
	@Autowired
	private LoginLogService<LoginLog> loginLogService;
	
	/**
	 * 定义切入点，切入点为'MsgEmity com.t.bricks.bussiness.server.login.impl.LoginServerImpl'下的in函数,并且函数只有3个参数(用?会异常)
	 * 1、execution(public * *(..)) 任意的公共方法
	 * 2、execution(* set*(..)) 以set开头的所有的方法
	 * 3、execution(* com.lingyejun.annotation.LoggerApply.*(..))com.lingyejun.annotation.LoggerApply这个类里的所有的方法
	 * 4、execution(* com.lingyejun.annotation.*.*(..))com.lingyejun.annotation包下的所有的类的所有的方法
	 * 5、execution(* com.lingyejun.annotation..*.*(..))com.lingyejun.annotation包及子包下所有的类的所有的方法
	 * 6、execution(* com.lingyejun.annotation..*.*(String,?,Long)) com.lingyejun.annotation包及子包下所有的类的有三个参数，第一个参数为String类型，第二个参数为任意类型，第三个参数为Long类型的方法
	 * 7、execution(@annotation(com.lingyejun.annotation.Lingyejun))
	 */
	@Pointcut(value = "execution(com.t.bricks.model.MsgEmity com.t.bricks.bussiness.server.login.impl.LoginServer*.in(String,String,String,Integer))")
	public void inMethod() {
	}

	/**
	 * 后置/返回值增强
     * @param joinPoint
     * @param result 被切点方法执行后的返回值
     * @return
	 */
	@AfterReturning(returning="result", pointcut="inMethod()")
	public void afterReturningByIn(JoinPoint joinPoint, Object result) {
		if (!(result instanceof MsgEmity)) {//不是返回MsgEmity,则说明不是要进行的
			MethodSignature signature = (MethodSignature) joinPoint.getSignature();
			String methodName = signature.getMethod().getName();
			Log.error("方法'", methodName, "'返回数据不是MsgEmity");
			return;
		}

		MsgEmity me = (MsgEmity)result;
		if (!me.isSuccess()) {
			return;			//原方法执行失败,不处理
		}
		
		add(joinPoint, me);	//多线程处理
	}

	/**
	 * 添加数据
	 * @param joinPoint
	 * @param msgEmity
	 */
	private void add(JoinPoint joinPoint, MsgEmity msgEmity) {
		Object[] methodArgs = joinPoint.getArgs();
		if (null == methodArgs || methodArgs.length < 4) {
			return;
		}
		
		String sOwner = String.valueOf(methodArgs[3]);
		if (null == sOwner || !sOwner.contains("BricksBaseSystem.")) {
			return;//非基本系统服务库下的操作
		}

		String sIp = ModuleUtil.currentLoginUserIp();
		
		ModuleUtil.runThread(() -> {//多线程方式重新构造缓存数据
			loginLogService.addByAop(sIp, String.valueOf(methodArgs[0]));//第一个参数为用户登录名(或工号)
		});
	}
		
}
